package com.github.phoenics.newlives.common.exception;

import com.github.phoenics.newlives.common.base.RestResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 基础异常处理
 *
 * @author Phoenics Chow
 * on 2019年09月24日
 */
@Slf4j
public class GlobalExceptionHandler {
    @ExceptionHandler(CommonApiException.class)
    public RestResponse handleException(CommonApiException ex, HttpServletResponse response) {
        RestResponse restResponse=null;
        if(ex.getErrorKey()!=null){
            restResponse = ApiExceptionUtils.getApiExceptionByErrorKey(ex.getErrorKey(), ex.getArgs());
            if(restResponse!= null){
//                if(restResponse.getStatus()>=400 && restResponse.getStatus()< 500){
//                    response.setStatus(restResponse.getStatus());
//                }
                return restResponse;
            }
            log.error("errorkey [{}] can't find value", ex.getErrorKey());
        }
        return getDefaultCommonExceptionResponse(ex);
    }

    //校验处理
    @ExceptionHandler({BindException.class})
    public RestResponse handleException(BindException e, HttpServletResponse response) {
        String message = getErrorMessage(e.getAllErrors());
        RestResponse restResponse = ApiExceptionUtils.getApiExceptionByErrorKey("field.error", message);
        //response.setStatus(restResponse.getStatus());
        return restResponse;
    }
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public RestResponse handleException(MethodArgumentNotValidException e, HttpServletResponse response) {
        BindingResult bindResult = e.getBindingResult();
        if (bindResult != null) {
            String message = getErrorMessage(bindResult.getAllErrors());
            RestResponse restResponse = ApiExceptionUtils.getApiExceptionByErrorKey("field.error", message);
            //response.setStatus(restResponse.getStatus());
            return restResponse;
        }else {
            return getDefaultCommonExceptionResponse(e);
        }
    }

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public RestResponse handleException(MissingServletRequestParameterException e, HttpServletResponse response) {
        StringBuilder message = new StringBuilder();
        message.append(e.getParameterName());
        message.append(":");
        message.append("不能为空");
        RestResponse restResponse = ApiExceptionUtils.getApiExceptionByErrorKey("field.error", message.toString());
        //response.setStatus(restResponse.getStatus());
        return restResponse;
    }
    @ExceptionHandler({IllegalArgumentException.class})
    public RestResponse handleException(IllegalArgumentException e, HttpServletResponse response) {
        RestResponse restResponse = ApiExceptionUtils.getApiExceptionByErrorKey("field.error", e.getMessage());
        //response.setStatus(restResponse.getStatus());
        return restResponse;
    }
    private String getErrorMessage(List<ObjectError> errors) {
        StringBuilder errorMessage = new StringBuilder();
        for (ObjectError error : errors) {
            if (error instanceof FieldError) {
                FieldError fieldError = (FieldError) error;
                errorMessage.append(fieldError.getField());
                errorMessage.append(":");
                errorMessage.append(fieldError.getDefaultMessage());
                errorMessage.append(",");
            }
        }
        String message = errorMessage.toString();
        if (errorMessage.length() > 0) {
            message = errorMessage.substring(0, errorMessage.length() - 1);
        }
        return message;
    }

    private RestResponse getDefaultCommonExceptionResponse(Exception e) {
        log.error("can't get ExceptionResponse from error property", e);
        e.printStackTrace();
        return RestResponse.exception(500,"未知异常");
    }

}
